AWS IAM Identity Centerの2つのセッション、アクセスポータルとIAMロールの違いについて
AWSのSSOサービス「AWS IAM Identity Center」では、AWSアクセスポータルで認証後、操作対象のAWSアカウントのIAMロールに対する一時認証を取得(STS相当)します。つまり、以下の2種類のセッション期間が存在します
- AWSアクセスセンターへのサインインに対するセッション期間(Identity Center単位で指定。デフォルトは8時間)
- IAM ロールに対するセッション期間(許可セット単位で指定。デフォルトは1時間)
2つ目については、セッションが切れた後も、1つ目のセッションが有効であればリフレッシュ可能であり、無効になった後はIdentity Centerへのサインインが求められます。
ただし、AWS CLIは2つ目のセッションが切れたときに自動的にリフレッシュを試みるため、2つ目の設定が機能しているか、わかりにくいところがあります。
以下では、それぞれのセッションの期限の設定方法を紹介し、AWS CLIからの動作を例に確認します。
前提知識となるIAMロールの操作、例えば STS:AssumeRole 等については、次の過去ブログを参照ください
セッションの設定
2つのセッションの期限の設定方法を確認します。
AWSアクセスポータルへのサインインセッション
AWSアクセスポータルへのサインインのセッション期間はデフォルトでは8時間であり、15分から90日の間で指定できます。
IAM Identity Center > Settings > Session settings から設定可能です。
There are two types of authentication sessions maintained by IAM Identity Center: one to represent the users’ sign in to IAM Identity Center, and another to represent the users’ access to AWS managed applications ... Each time a user signs in to IAM Identity Center, a sign in session is created for the duration configured in IAM Identity Center, which can be up to 90 days.
https://docs.aws.amazon.com/singlesignon/latest/userguide/authconcept.html
IAMロールセッション
操作対象のAWSアカウントのIAMロールを assume するセッション期間はデフォルトでは1時間であり、1時間から12時間の間で指定できます。
IAM Identity Center の 許可セット単位で設定可能です。
When users federate into their AWS account console or when the AWS Command Line Interface (AWS CLI) is used, IAM Identity Center uses the session duration setting on the permission set to control the duration of the session.
https://docs.aws.amazon.com/singlesignon/latest/userguide/howtosessionduration.html
ユースケースで考える
話を単純化するために、AWS CLIでIAM Identity Center配下のAWSアカウントを操作することを考えます。
ケース1:初めてアクセスポータルと認証する場合
初めてAWS CLI設定でIdentity Centerと連携する場合は $ aws sso configure
、初期設定済みでその日初めてのコマンド実行の場合は、$ aws sso login
でAWSアクセスポータルと認証し、アクセストークンを入手します。
$ aws sso login --profile ReadOnlyAccess-123
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
https://device.sso.us-east-1.amazonaws.com/
Then enter the code:
ABCD-EFGH
Successfully logged into Start URL: https://d-123.awsapps.com/start
$
この認証セッションが IAM Identity Center単位で指定する期間(デフォルトは8時間)です。
認証トークンは $HOME/.aws/sso/cache
以下で sso_start_url
に基づいたファイル名でキャッシュされます。
$ find .aws/
.aws/
.aws/sso
.aws/sso/cache
.aws/sso/cache/aaa.json
.aws/sso/cache/bbb.json
.aws/config
.aws/cli
.aws/cli/cache
$ jq . < .aws/sso/cache/bbb.json
{
"clientId": "your-client-id",
"clientSecret": "AAA.BBB.CCC",
"expiresAt": "2024-12-28T07:56:50Z",
"scopes": [
"sso:account:access"
]
}
$ jq . < .aws/sso/cache/aaa.json
{
"startUrl": "https://d-123.awsapps.com/start",
"region": "us-east-1",
"accessToken": "XXX.YYY.ZZZ",
"expiresAt": "2024-09-29T11:52:31Z",
"clientId": "your-client-id",
"clientSecret": "AAA.BBB.CCC",
"registrationExpiresAt": "2024-12-28T07:56:50Z",
"refreshToken": "xxx"
}
2つ目のキャッシュファイルにおいて、アクセスポータルのセッション期間は8時間ですが、初回認証時のexpiresAt
は1時間後に設定されます。、IAMロールセッションの取得などIdentity Centerとの通信を伴うときに、expire している場合、セッション期間を過ぎていなければ、1時間後に再設定されます。
この状態で $ aws s3 ls --profile ReadOnlyAccess-123456789012
のようにAWSリソースを操作すると、裏では先ほど入手した認証トークンを利用し、操作対象のAWSアカウントとIAMロールを指定して、IAMロールの一時認証情報を取得します。
このセッションが許可セット単位で指定する期間(デフォルトは1時間)です。
$ find .aws/
.aws/
.aws/sso
.aws/sso/cache
.aws/sso/cache/aaa.json
.aws/sso/cache/bbb.json
.aws/config
.aws/cli
.aws/cli/cache
.aws/cli/cache/ccc.json
クライアントがAssumeする認証トークンは $HOME/.aws/cli/cache
以下でキャッシュされます。
$ jq . < .aws/cli/cache/ccc.json
{
"ProviderType": "sso",
"Credentials": {
"AccessKeyId": "aaa",
"SecretAccessKey": "bbb",
"SessionToken": "AAA.BBB.CCC",
"Expiration": "2024-09-29T12:00:15Z"
}
}
Expiration
にはAWS APIの呼び出し時刻を起点に許可セットのセッション期間分だけ未来の有効期限が設定されています。
内部的には SSO:GetRoleCredentials というAPIを呼び出しており、APIドキュメントに "Returns the STS short-term credentials for a given role name that is assigned to the user." とあるように、STS::AssumeRole の IAM Identity Center 版です。
STS::AssumeRole
のように環境変数に渡して利用することもできます。
$ export AWS_ACCESS_KEY_ID=AS...
$ export AWS_SECRET_ACCESS_KEY=your-secret-access-key
$ export AWS_SESSION_TOKEN=your-session-token
$ aws s3 ls
STS::AssumeRole
ではセッション時間を DurationSeconds
で動的に指定できますが、SSO:GetRoleCredentials
は許可セットで指定した期間に固定されます。
ケース2:アクセスポータルのセッションが有効でIAMロールのセッションが無効な場合
IAMロールに対する一時トークンの有効期限が過ぎた状態で、再度AWSリソースを操作するコマンドを実行することを考えます。
この時に、アクセスポータルのセッションが有効であれば、IAMロールのセッショントークンのリフレッシュが可能です。
AWS CLIはIAMロールのセッションが切れている場合、暗黙にトークンのリフレッシュを試みるため、許可セットのセッション期間を意識する機会はあまりないでしょう。
コマンド実行時に --debug
オプションを付与すると、確かにトークンのリフレッシュ操作を確認できます
$ aws s3 ls --debug
...
2024-09-29 13:53:57,098 - MainThread - botocore.credentials - DEBUG - Credentials were found in cache, but they are expired.
...
2024-09-29 13:53:57,104 - MainThread - botocore.endpoint - DEBUG - Making request for OperationModel(name=CreateToken) with params: {'url_path': '/token', 'query_string': {}, 'method': 'POST', 'headers': {'Content-Type': 'application/json', 'User-Agent': 'aws-cli/2.17.27 md/awscrt#0.21.2 ua/2.0 os/macos#23.3.0 md/arch#arm64 lang/python#3.11.9 md/pyimpl#CPython cfg/retry-mode#standard md/installer#source md/prompt#off md/command#s3.ls'}, 'body': b'{"grantType": "refresh_token", "clientId": "xxx", "clientSecret": "eyJraWQiO
...
2024-09-29 13:53:58,124 - MainThread - botocore.tokens - INFO - SSO Token refresh succeeded
この状態で $HOME/.aws/cli/cache
配下のキャッシュファイルの Expiration
フィールドを確認すると、現在時刻を起点に許可セットのセッション期間分だけ未来の有効期限に更新されています。
ケース3:アクセスポータルのセッションが無効でIAMロールのセッションが無効な場合
アクセスポータルのセッションが失効している状況でIAMロールの一時トークンをリフレッシュしようとすると、以下の様にトークンのリフレッシュに失敗した旨のエラーメッセージが表示されます。
$ aws s3 ls --profile ReadOnlyAccess-123456789012
Error when retrieving token from sso: Token has expired and refresh failed
アクセスポータルと再認証($ aws sso login
)した後で、AWS CLI操作をすると、IAMロールのトークンが更新され、API実行が成功するようになります。
ケース4:アクセスポータルのセッションが無効でIAMロールのセッションが有効な場合
アクセスポータルのセッションが切れているけれども、ロールの一時トークンのセッションが有効な場合はどうでしょうか?
この場合、払い出し済みのIAMロールの一時トークンが失効しない限り有効です。
ケース5:アクセスポータルのセッションを削除した場合
IAM Identity Centerは各ユーザーのアクセスポータルとのアクティブなセッションを削除する機能があります。この操作を行ってセッションを無効化すると、AWS CLIにはどのような影響があるでしょうか?
この場合も、払い出し済みのIAMロールの一時トークンが失効しない限り有効です。
アクセスポータルセッションの削除時のポップアップにも注意書きがあります
Management console and CLI sessions will remain active until the session expires.
ケース4と同じ状況です。
aws sso logout したら?
aws sso には logout というサブコマンドがあり、キャッシュされたクレデンシャルを削除できます。
$ find .aws
.aws
.aws/sso
.aws/sso/cache
.aws/sso/cache/aaa.json
.aws/sso/cache/bbb.json
.aws/config
.aws/cli
.aws/cli/cache
.aws/cli/cache/ccc.json
この状態で aws sso logout
します。
$ aws sso logout --profile ReadOnlyAccess-123456789012
$ find .aws/
.aws/
.aws/sso
.aws/sso/cache
.aws/sso/cache/bbb.json
.aws/config
.aws/cli
.aws/cli/cache
次回、AWS CLI呼び出し時には $ aws sso login
からやり直しです。
最後に
AWS IAM Identity CenterにはAWSアクセスポータルとIAMロールの2つのセッションが存在し、全社はIAM Identity Center単位で指定(デフォルトは8時間)、後者は許可セット単位で指定(デフォルトは1時間)します。
1つ目のセッションは2つ目のセッションを取得するために使われ、1つ目のセッションの有効期限に関係なく、2つ目のセッションが有効な限り、AWSリソースを操作できます。ドキュメントから引用します。
When the user uses IAM Identity Center to access the AWS Management Console or CLI, the IAM Identity Center sign in session is used to obtain an IAM session, as specified in the corresponding IAM Identity Center permission set (more specifically, IAM Identity Center assumes an IAM role, which IAM Identity Center manages, in the target account). IAM sessions persist for the time specified for the permission set, unconditionally.
https://docs.aws.amazon.com/singlesignon/latest/userguide/authconcept.html
AWS CLIの場合、2つ目のセッションが切れると、自動的にセッションを更新し、1つ目のセッションが切れるまでは更新に成功するため、2つ目のセッション設定が機能していないように見えます。ただし、AWS CLIのデバッグログをよく確認すると、2つ目のセッションが切れた時には、自動的にリフレッシュされているのが原因とわかります。
同僚の平井さんから過去に書いたIAM Identity Centerのブログについてセッション部分について質問があり、改めて読むと、2つのセッションを区別してい無いことに気づきました。IAM Identity Centerのセッションを切り口に新規に調査した内容を本ブログとして切り出しました。また、次の過去ブログについても、2つのセッションを明確に分けて解説して更新済みです。お気に入りブログなので、ぜひご一読ください。
それでは。
参考
- AWS CLIをAWS IAM Identity Center(SSO)で認証させるには? | DevelopersIO
- Configure the AWS CLI with IAM Identity Center authentication - AWS Command Line Interface
- Authentication in IAM Identity Center - AWS IAM Identity Center
- Configure the session duration of the AWS access portal and IAM Identity Center integrated applications - AWS IAM Identity Center
- v2 Session Duration of Permission Set is not respected by AWS CLI · Issue #7104 · aws/aws-cli